/**
 * \file Graphe.cpp
 * \brief Tests unitaires de la classe Graphe
 * \author Pierre-Marc Levasseur, Simon Rodier
 * \version 0.1
 * \date juillet 2014
 *
 *  Travail pratique numéro 3
 *
 */

#include"Graphe.h"
#include<gtest/gtest.h>
#include <math.h>

using namespace std;
using namespace TP3;

TEST(Graphe, nombreSommets_aucunSommet_renvoieZero)
{
	Graphe g;

	ASSERT_EQ(0, g.nombreSommets());
}

TEST(Graphe, ajouterSommet_ajoutDUnSommet_leGrapheAUnSommet)
{
	Graphe g;

	g.ajouterSommet("Quebec", 46.80, -71.24);

	ASSERT_EQ(1, g.nombreSommets());
	ASSERT_TRUE(g.sommetExiste("Quebec"));
	ASSERT_FALSE(g.estVide());
}

TEST(Graphe, ajouterSommet_ajoutDeDeuxSommets_leGrapheADeuxSommets)
{
	Graphe g;

	g.ajouterSommet("Quebec", 46.80, -71.24);
	g.ajouterSommet("Montreal", 45.51, -73.55);

	ASSERT_EQ(2, g.nombreSommets());
	ASSERT_TRUE(g.sommetExiste("Quebec"));
	ASSERT_TRUE(g.sommetExiste("Montreal"));
}

TEST(Graphe, ajouterSommet_ajoutDePlusieursSommets_leGrapheALeBonNombreDeSommet)
{
	Graphe g;

	g.ajouterSommet("Quebec", 46.80, -71.24);
	g.ajouterSommet("Montreal", 45.51, -73.55);
	g.ajouterSommet("Detroit",42.33, -83.05);
	g.ajouterSommet("Ottawa", 45.41, -75.70);
	g.ajouterSommet("Vancouver", 49.26, -123.12);
	g.ajouterSommet("Toronto", 43.65, -79.38);

	ASSERT_EQ(6, g.nombreSommets());
}

TEST(Graphe, operateurAssignation_contientLesBonsSommetsEtArcs)
{
	Graphe grapheTest;
	{
		Graphe g;
		g.ajouterSommet("Quebec", 46.80, -71.24);
		g.ajouterSommet("Montreal", 45.51, -73.55);
		g.ajouterSommet("Detroit",42.33, -83.05);
		g.ajouterSommet("Ottawa", 45.41, -75.70);
		g.ajouterSommet("Vancouver", 49.26, -123.12);
		g.ajouterSommet("Toronto", 43.65, -79.38);
		g.ajouterArc("Quebec", "Montreal", 2, 299, -1);
		g.ajouterArc("Montreal", "Quebec", 3, 100, -2);
		g.ajouterArc("Quebec", "Vancouver", 3, 599, 6);
		g.ajouterArc("Toronto", "Vancouver", 7, 600, 2);
		grapheTest = g;
	}


	ASSERT_TRUE(grapheTest.nombreSommets()==6);
	ASSERT_TRUE(grapheTest.sommetExiste("Quebec"));
	ASSERT_TRUE(grapheTest.sommetExiste("Montreal"));
	ASSERT_TRUE(grapheTest.sommetExiste("Detroit"));
	ASSERT_TRUE(grapheTest.sommetExiste("Ottawa"));
	ASSERT_TRUE(grapheTest.sommetExiste("Vancouver"));
	ASSERT_TRUE(grapheTest.sommetExiste("Toronto"));
	ASSERT_TRUE(grapheTest.getNombreArcs()==4);
}

TEST(Graphe, getCoordonneesSommet_aucunSommetDansLeGraphe_logicError)
{
	Graphe g;
	ASSERT_THROW(g.getCoordonneesSommet("Tomate"), logic_error);
}

class GrapheTest : public ::testing::Test
{
public:
	GrapheTest():g()
	{
		g.ajouterSommet("Quebec", 46.80, -71.24);
		g.ajouterSommet("Montreal", 45.51, -73.55);
		g.ajouterSommet("Detroit",42.33, -83.05);
		g.ajouterSommet("Ottawa", 45.41, -75.70);
		g.ajouterSommet("Vancouver", 49.26, -123.12);
		g.ajouterSommet("Toronto", 43.65, -79.38);
	}
	Graphe g;
};

TEST_F(GrapheTest, constructeurCopie_contientLesBonsSommetsEtArcs)
{
	g.ajouterArc("Quebec", "Montreal", 2, 299, -1);
	g.ajouterArc("Montreal", "Quebec", 3, 100, -2);
	g.ajouterArc("Quebec", "Vancouver", 3, 599, 6);
	g.ajouterArc("Toronto", "Vancouver", 7, 600, 2);

	Graphe grapheTest(g);

	ASSERT_TRUE(grapheTest.nombreSommets()==6);
	ASSERT_TRUE(grapheTest.sommetExiste("Quebec"));
	ASSERT_TRUE(grapheTest.sommetExiste("Montreal"));
	ASSERT_TRUE(grapheTest.sommetExiste("Detroit"));
	ASSERT_TRUE(grapheTest.sommetExiste("Ottawa"));
	ASSERT_TRUE(grapheTest.sommetExiste("Vancouver"));
	ASSERT_TRUE(grapheTest.sommetExiste("Toronto"));
	ASSERT_TRUE(grapheTest.getNombreArcs()==4);
}

TEST_F(GrapheTest, enleverSommet_EnleveUnSommet_GrapheAUnSommetDeMoins)
{
	g.enleverSommet("Detroit");

	ASSERT_EQ(5, g.nombreSommets());
}

TEST_F(GrapheTest, enleverSommet_EnlevePremierSommetDeLaListe_GrapheAUnSommetDeMoins)
{
	g.enleverSommet("Quebec");

	ASSERT_EQ(5, g.nombreSommets());
}

TEST_F(GrapheTest, enleverSommet_EnleveDernierSommetDeLaListe_GrapheAUnSommetDeMoins)
{
	g.enleverSommet("Toronto");

	ASSERT_EQ(5, g.nombreSommets());
}

TEST_F(GrapheTest, enleverSommet_EnleveTousLesSommetsDeLaListe_GrapheAAucunSommet)
{
	g.enleverSommet("Quebec");
	g.enleverSommet("Montreal");
	g.enleverSommet("Detroit");
	g.enleverSommet("Ottawa");
	g.enleverSommet("Vancouver");
	g.enleverSommet("Toronto");

	ASSERT_EQ(0, g.nombreSommets());
}

TEST_F(GrapheTest, ajouterSommet_ajoutDUnSommetExistant_LeveUneException)
{
	ASSERT_THROW(g.ajouterSommet("Quebec", 46.80, -71.24), logic_error);
}

TEST_F(GrapheTest, ajouterArc_ajoutDunArc_ArcAjouteExiste)
{
	g.ajouterArc("Quebec", "Montreal", 0.8, 500, 4);

	ASSERT_TRUE(g.arcExiste("Quebec", "Montreal"));
}

TEST_F(GrapheTest, ajouterArc_ajoutDePlusieursArcs_TousLesArcsExistent)
{
	g.ajouterArc("Quebec", "Montreal", 0.8, 500, 4);
	g.ajouterArc("Quebec", "Toronto", 1.8, 800, 7);
	g.ajouterArc("Detroit", "Vancouver", 4.5, 1200, 4);
	g.ajouterArc("Ottawa", "Quebec", 1.2, 800, 4);
	g.ajouterArc("Toronto", "Quebec", 0.8, 600, -5);
	g.ajouterArc("Detroit", "Toronto", 0.9, 800, -3);
	g.ajouterArc("Montreal", "Quebec", 0.8, 500, 4);

	ASSERT_TRUE( g.arcExiste("Quebec", "Montreal"));
	ASSERT_TRUE( g.arcExiste("Quebec", "Toronto"));
	ASSERT_TRUE( g.arcExiste("Detroit", "Vancouver"));
	ASSERT_TRUE( g.arcExiste("Ottawa", "Quebec"));
	ASSERT_TRUE( g.arcExiste("Toronto", "Quebec"));
	ASSERT_TRUE( g.arcExiste("Detroit", "Toronto"));
	ASSERT_TRUE( g.arcExiste("Montreal", "Quebec"));
}

TEST_F(GrapheTest, ajouterArc_ajoutDunArcAvecSommetNonExistant_LeveUneException)
{
	ASSERT_THROW(g.ajouterArc("Drummondville", "Montreal", 0.5, 500, 6), logic_error);
}

TEST_F(GrapheTest, ajouterArc_ajoutDeuxFoisMemeArc_LeveUneExceptionLaDeuxiemeFois)
{
	g.ajouterArc("Quebec", "Montreal", 0.8, 500, 4);
	ASSERT_THROW(g.ajouterArc("Quebec", "Montreal", 0.8, 500, 4), logic_error);
}

TEST_F(GrapheTest, getNomSommets_cestLeBonSommet)
{
	ASSERT_TRUE(g.getNomSommet(45.41, -75.70)=="Ottawa");
}

TEST_F(GrapheTest, getNomSommets_sommetNExistePas_logicError)
{
	ASSERT_THROW(g.getNomSommet(1, 1), logic_error);
}

TEST_F(GrapheTest, getCoordonneesSommets_coordonneesCorrect)
{
	ASSERT_TRUE(g.getCoordonneesSommet("Vancouver").lt==(float)49.26 && g.getCoordonneesSommet("Vancouver").lg==(float)-123.12);
}

TEST_F(GrapheTest, getCoordonneesSommets_sommetNexistePas_logicError)
{
	ASSERT_THROW(g.getCoordonneesSommet("Tomate"), logic_error);
}







TEST_F(GrapheTest, getDistance_distanceEstBonne)
{
	ASSERT_TRUE((g.getDistance("Quebec", "Montreal")==(float)sqrt(pow(((float)45.51-(float)46.80),2)+pow(((float)-73.55-(float)(-71.24)),2))));
}

TEST_F(GrapheTest, getDistance_sommetDepartNExistePas_logicError)
{
	ASSERT_THROW(g.getDistance("tomate", "Montreal"), logic_error);
}

TEST_F(GrapheTest, getDistance_sommetArriveeNExistePas_logicError)
{
	ASSERT_THROW(g.getDistance("Quebec", "Patate"), logic_error);
}



TEST_F(GrapheTest, listerNomsSommets_tousLesSommetsSontDansLaListe)
{
	vector<string> nomsDesSommets;
	nomsDesSommets.push_back("Quebec");
	nomsDesSommets.push_back("Montreal");
	nomsDesSommets.push_back("Detroit");
	nomsDesSommets.push_back("Ottawa");
	nomsDesSommets.push_back("Vancouver");
	nomsDesSommets.push_back("Toronto");
	ASSERT_TRUE(nomsDesSommets == g.listerNomsSommets());
}

class GrapheTest2 : public ::testing::Test
{
public:
	GrapheTest2():g()
	{
		g.ajouterSommet("Quebec", 46.80, -71.24);
		g.ajouterSommet("Montreal", 45.51, -73.55);
		g.ajouterSommet("Detroit",42.33, -83.05);
		g.ajouterSommet("Ottawa", 45.41, -75.70);
		g.ajouterSommet("Vancouver", 49.26, -123.12);
		g.ajouterSommet("Toronto", 43.65, -79.38);

		g.ajouterArc("Quebec", "Montreal", 0.8, 500, 4);
		g.ajouterArc("Quebec", "Toronto", 1.8, 800, 7);
		g.ajouterArc("Detroit", "Vancouver", 4.5, 1200, 4);
		g.ajouterArc("Ottawa", "Quebec", 1.2, 800, 4);
		g.ajouterArc("Toronto", "Quebec", 0.8, 600, -5);
		g.ajouterArc("Detroit", "Toronto", 0.9, 800, -3);
		g.ajouterArc("Montreal", "Quebec", 0.8, 500, 4);
	}
	Graphe g;
};

// Les 4 prochains tests sont des doublons de tests effectué précédement, je veux faire les même
// tests avec un graphe qui a des arcs

TEST_F(GrapheTest2, enleverSommet_EnleveUnSommet_GrapheAUnSommetDeMoins)
{
	g.enleverSommet("Detroit");

	ASSERT_EQ(5, g.nombreSommets());
}

TEST_F(GrapheTest2, enleverSommet_EnlevePremierSommetDeLaListe_GrapheAUnSommetDeMoins)
{
	g.enleverSommet("Quebec");

	ASSERT_EQ(5, g.nombreSommets());
}

TEST_F(GrapheTest2, enleverSommet_EnleveDernierSommetDeLaListe_GrapheAUnSommetDeMoins)
{
	g.enleverSommet("Toronto");

	ASSERT_EQ(5, g.nombreSommets());
}

TEST_F(GrapheTest2, enleverSommet_EnleveTousLesSommetsDeLaListe_GrapheAAucunSommet)
{
	g.enleverSommet("Quebec");
	g.enleverSommet("Montreal");
	g.enleverSommet("Detroit");
	g.enleverSommet("Ottawa");
	g.enleverSommet("Vancouver");
	g.enleverSommet("Toronto");

	ASSERT_EQ(0, g.nombreSommets());
	ASSERT_TRUE(g.estVide());
}

TEST_F(GrapheTest2, enleverArc_EnleveUnArc_CetArcNExistePlus)
{
	g.enleverArc("Quebec", "Montreal");

	ASSERT_FALSE(g.arcExiste("Quebec", "Montreal"));
}

TEST_F(GrapheTest2, enleverArc_EnleveUnArc_CetArcNExistePlus2)
{
	g.enleverArc("Detroit", "Toronto");

	ASSERT_FALSE(g.arcExiste("Detroit", "Toronto"));
}

TEST_F(GrapheTest2, setSommetsFalse_tousLesSommetsSontAFalse)
{
	g.setSommetsFalse();

	ASSERT_FALSE(g.getSommetEtat("Quebec"));
	ASSERT_FALSE(g.getSommetEtat("Montreal"));
	ASSERT_FALSE(g.getSommetEtat("Detroit"));
	ASSERT_FALSE(g.getSommetEtat("Ottawa"));
	ASSERT_FALSE(g.getSommetEtat("Vancouver"));
	ASSERT_FALSE(g.getSommetEtat("Toronto"));
}

TEST_F(GrapheTest2, setSommetEtat_onMetLetatDunSommetATrue_LeSommetEstBienATrue)
{
	g.setSommetEtat("Quebec", true);

	ASSERT_TRUE(g.getSommetEtat("Quebec"));
}

TEST_F(GrapheTest2, setSommetEtat_onMetLetatDunSommetATrue_LeSommetEstBienATrue2)
{
	g.setSommetEtat("Detroit", true);

	ASSERT_TRUE(g.getSommetEtat("Detroit"));
}

TEST_F(GrapheTest2, setSommetEtat_onMetLetatDunSommetATrue_LeSommetEstBienATrue3)
{
	g.setSommetEtat("Toronto", true);

	ASSERT_TRUE(g.getSommetEtat("Toronto"));
}

TEST_F(GrapheTest2, listerSommetsAdjacents_recupereLaListeDesSommetsAdjDuneVille_LaListeContienLesBonsSommets)
{
	vector<string> sommetAdj = g.listerSommetsAdjacents("Quebec");

	ASSERT_EQ(2, sommetAdj.size());
	ASSERT_EQ("Montreal", sommetAdj[0]);
	ASSERT_EQ("Toronto", sommetAdj[1]);
}

TEST_F(GrapheTest2, listerSommetsAdjacents_recupereLaListeDesSommetsAdjDuneVille_LaListeContienLesBonsSommets2)
{
	vector<string> sommetAdj = g.listerSommetsAdjacents("Vancouver");

	ASSERT_TRUE(sommetAdj.empty());
}

TEST_F(GrapheTest2, getPonderationsArc_laPonderationEstBonne)
{
	ASSERT_TRUE(g.getPonderationsArc("Quebec", "Montreal").cout == (float)500);
	ASSERT_TRUE(g.getPonderationsArc("Quebec", "Montreal").duree == (float)0.8);
	ASSERT_TRUE(g.getPonderationsArc("Quebec", "Montreal").ns == (int)4);
}

TEST_F(GrapheTest2, getPonderationsArc_sommetSourceNExistePas_logicError)
{
	ASSERT_THROW(g.getPonderationsArc("Tomate", "Montreal"), logic_error);
}

TEST_F(GrapheTest2, getPonderationsArc_sommetDestNExistePas_logicError)
{
	ASSERT_THROW(g.getPonderationsArc("Quebec", "Patate"), logic_error);
}

TEST_F(GrapheTest2, getPonderationsArc_arcNExistePas_logicError)
{
	ASSERT_THROW(g.getPonderationsArc("Montreal", "Vancouver"), logic_error);
}
